KVO 官方翻译文档
KVC Collection Operators
注册方式
addObserver:(NSObject )observer forKeyPath:(NSString )keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
The context pointer can be a C pointer or an object reference. The context pointer can be used as a unique identifier to determine the change that is being observed, or to provide some other data to the observer.
Note:
The key-value observing addObserver:forKeyPath:options:context: method does not maintain strong references to the observing object, the observed objects, or the context. You should ensure that you maintain strong references to the observing, and observed, objects, and the context as necessary.
|
|
如果Value属性是个对象,直接传递,如果是the property is a scalar or a C structure,通过KVC取值
|
|
如果context是个对象,在remove前必须保持强持有
|
|
KVO Compliance
前提
- 该类提供必要的方法使这个property 是KVC Compliant的。
- 这个类能正确发出KVO change notification;
- 若某个Property依赖于其他几个Property(称为dependent keys),都应该被注册好.
自动KVO
如果我们使用Accessor方法或者KVC 方法(setValue:forKey setValue:forKeyPath等)改变属性的值都会自动发出notification。
手动KVO
Manual change notification往往配合automaticallyNotifiesObserversForKey:一起使用。如果一个Property已经是KVC Compliant的了,那意味着这个Property已经默认支持automatic notification了,我们要让其做manaul notification,就要覆盖automaticallyNotifiesObserversForKey:,使其不要多automatic notification。但是如果一个instance variable或者attribute并不是KVC Compliance的,而它仍然希望发出notification,那么就不需要覆盖automaticallyNotifiesObserversForKey:了。下面是一个automaticallyNotifiesObserversForKey:的例子:
|
|
将automatic notification关闭后,就需要调用willChangeValueForKey:didChangeValueForKey:来实现通知行为,如果一个操作导致多个key发生变化,需要嵌套调用。
>
In the case of an ordered to-many relationship, you must specify not only the key that changed, but also the type of change and the indexes of the objects involved. The type of change is an NSKeyValueChange that specifies NSKeyValueChangeInsertion, NSKeyValueChangeRemoval, or NSKeyValueChangeReplacement. The indexes of the affected objects are passed as an NSIndexSet object.
|
|
Registering Dependent Keys
property 的值依赖于其他对象的多个属性时,如何解决
对某个属性(应该是说有限长度的属性)计算属性
|
|
一是可以覆盖keyPathsForValuesAffectingValueForKey:(NSString *)key方法,先调用super,在添加keyPath
|
|
二是也可以通过遵循 naming convention 的 class method 来完成同样的功能用keyPathsForValuesAffecting方式生成keyPath
|
|
>
Note:
You can’t override the keyPathsForValuesAffectingValueForKey: method when you add a computed property to an existing class using a category, because you’re not supposed to override methods in categories. In that case, implement a matching keyPathsForValuesAffecting class method to take advantage of this mechanism.
对多:(应该是指不定长度)
情景:某部门有多个员工,你需要有这个部门所有员工的工资属性,这时不能用keyPathsForValuesAffectingTotalSalary 并且返回employees.salary作为key
- 你可以多其父类(部门)进行KVO,对相关的孩子(员工)进行观察。并且在observeValueForKeyPath:ofObject:change:context: 方法中更新变化
|
|
- Core Data
If you’re using Core Data, you can register the parent with the application’s notification center as an observer of its managed object context. The parent should respond to relevant change notifications posted by the children in a manner similar to that for key-value observing
实现原理:
自动KVO是通过 isa-swizzling实现的
实例isa指针之乡对象类(Class A),里面有类实现方法及数据。当有观察者注册对象的属性后,isa指向SubClassA,因此实际的isa指针并不能真正反映出实例的真实类。
因此,不能依靠isa决定类的关系,而通过class method的方法。